import { createRouter, createWebHistory } from 'vue-router'
import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { Session } from '@/utils/storage'
import { useRouteStore } from '@/stores/modules/routeStore'

import { staticRoutes, notFoundAndNoPower, dynamicRoutes } from '@/router/route'
import { initBackEndControlRoutes } from '@/router/backEnd'
import { TOKEN_KEY } from '@/constants'

// 白名单路由
const whiteList = ['/login']

export const router = createRouter({
    history: createWebHistory(import.meta.env.VITE_PUBLIC_PATH),
    /**
     * 1、notFoundAndNoPower 默认添加 404、401 界面，防止一直提示 No match found for location with path 'xxx'
     * 2、backEnd.ts(后端控制路由)、frontEnd.ts(前端控制路由) 中也需要加 notFoundAndNoPower 404、401 界面。
     *    防止 404、401 不在 layout 布局中，不设置的话，404、401 界面将全屏显示
     */
    routes: [...notFoundAndNoPower, ...staticRoutes, ...dynamicRoutes],
})

router.beforeEach(async (to, from, next) => {
    NProgress.configure({ showSpinner: false })
    if (to.meta.title) NProgress.start()
    const token = Session.get(TOKEN_KEY)
    if (whiteList.includes(to.path)) {
        next()
        NProgress.done()
    } else {
        if (!token) {
            next(`/login?redirect=${to.path}&params=${JSON.stringify(to.query ? to.query : to.params)}`)
            Session.clear()
            NProgress.done()
        } else if (token && to.path === '/login') {
            next('/home')
            NProgress.done()
        } else {
            const routeStore = useRouteStore()
            const { routeList } = routeStore
            if (routeList.length === 0) {
                try {
                    await initBackEndControlRoutes()
                    next({ path: to.path, query: to.query })
                } catch (e) {
                    console.error(e)
                    redirectToLogin(to, next)
                }
            } else {
                next()
            }
        }
    }
})

const redirectToLogin = (to: RouteLocationNormalized, next: NavigationGuardNext) => {
    const params = new URLSearchParams(to.query as Record<string, string>)
    const queryString = params.toString()
    const redirect = queryString ? `${to.path}?${queryString}` : to.path
    next(`/login?redirect=${encodeURIComponent(redirect)}`)
}

// 路由加载后
router.afterEach(() => {
    NProgress.done()
})

// 导出路由
export default router
